﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace Song.Common.Tools
{
    /// <summary>
    /// This code is from 
    /// http://dotnetslackers.com/articles/aspnet/5-Helpful-DateTime-Extension-Methods.aspx
    /// </summary>
   public  static class DateTimeExtensions
    {
       /// <summary>
       /// 
       /// </summary>
       /// <param name="date"></param>
       /// <param name="days"></param>
       /// <returns></returns>
       public static DateTime AddWeekdays(this DateTime date, int days)
       {
           var sign = days < 0 ? -1 : 1;
           var unsignedDays = Math.Abs(days);
           var weekdaysAdded = 0;
           while (weekdaysAdded < unsignedDays)
           {
               date = date.AddDays(sign);
               if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
                   weekdaysAdded++;
           }
           return date;
       }

       public static DateTime SetTime(this DateTime date, int hour)
       {
           return date.SetTime(hour, 0, 0, 0);
       }
       public static DateTime SetTime(this DateTime date, int hour, int minute)
       {
           return date.SetTime(hour, minute, 0, 0);
       }
       public static DateTime SetTime(this DateTime date, int hour, int minute, int second)
       {
           return date.SetTime(hour, minute, second, 0);
       }
       public static DateTime SetTime(this DateTime date, int hour, int minute, int second, int millisecond)
       {
           return new DateTime(date.Year, date.Month, date.Day, hour, minute, second, millisecond);
       }

       public static DateTime FirstDayOfMonth(this DateTime date)
       {
           return new DateTime(date.Year, date.Month, 1);
       }
       public static DateTime LastDayOfMonth(this DateTime date)
       {
           return new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
       }

       public static string ToString(this DateTime? date)
       {
           return date.ToString(null, DateTimeFormatInfo.CurrentInfo);
       }
       public static string ToString(this DateTime? date, string format)
       {
           return date.ToString(format, DateTimeFormatInfo.CurrentInfo);
       }
       public static string ToString(this DateTime? date, IFormatProvider provider)
       {
           return date.ToString(null, provider);
       }
       public static string ToString(this DateTime? date, string format, IFormatProvider provider)
       {
           return date.HasValue ? date.Value.ToString(format, provider) : string.Empty;
       }

       public static string ToRelativeDateString(this DateTime date)
       {
           return GetRelativeDateValue(date, DateTime.Now);
       }
       public static string ToRelativeDateStringUtc(this DateTime date)
       {
           return GetRelativeDateValue(date, DateTime.UtcNow);
       }
       private static string GetRelativeDateValue(DateTime date, DateTime comparedTo)
       {
           TimeSpan diff = comparedTo.Subtract(date);
           if (diff.TotalDays >= 365)
               return string.Concat("on ", date.ToString("MMMM d, yyyy"));
           if (diff.TotalDays >= 7)
               return string.Concat("on ", date.ToString("MMMM d"));
           else if (diff.TotalDays > 1)
               return string.Format("{0:N0} days ago", diff.TotalDays);
           else if (diff.TotalDays == 1)
               return "yesterday";
           else if (diff.TotalHours >= 2)
               return string.Format("{0:N0} hours ago", diff.TotalHours);
           else if (diff.TotalMinutes >= 60)
               return "more than an hour ago";
           else if (diff.TotalMinutes >= 5)
               return string.Format("{0:N0} minutes ago", diff.TotalMinutes);
           if (diff.TotalMinutes >= 1)
               return "a few minutes ago";
           else
               return "less than a minute ago";
       }
    }
}
